<?php
/**
 * User: zhangligang
 * Email: tzhang2450@163.com
 * Date: 2018/7/27
 * Time: 上午6:40
 */

namespace App\Http\Controllers\V1;


use App\Http\Controllers\Controller;
use App\Models\Contract;
use App\Models\ProgramUser;
use App\Models\UserApart;
use App\Providers\MyJwt;
use App\Providers\XykOrder;
use App\Services\ApartService;
use App\Services\ContractService;
use App\Services\FeeService;
use App\Services\NoticeService;
use App\Services\ProgramService;
use App\Services\RentService;
use App\Services\RepairService;
use App\Services\RetireService;
use App\Services\UserService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redis;

class TeacherController extends Controller
{

    private $uid;

    public function __construct(Request $request)
    {
        parent::__construct();
        $authorization = $request->header('Authorization');
        $jwt = new MyJwt();
        $jwtCode = $jwt->decode($authorization, MyJwt::ENCODE_KEY);
        if (!$jwtCode || !array_key_exists('uid', $jwtCode)) {
            $this->sendJson([], 4031, '请登录');
        }
        if (!array_key_exists('role', $jwtCode) || $jwtCode['role'] != 1) {
            $this->sendJson([], 4032, '非法请求');
        }
        if (!array_key_exists('timeout', $jwtCode) || $jwtCode['timeout'] < time()) {
            $this->sendJson([], 4031, '请登录');
        }

        $cacheKey = sprintf('ht:login:uid:%d', $jwtCode['uid']);
        $cacheData = Redis::get($cacheKey);
        if (!$cacheData || $cacheData < time()) {
            Redis::setex($cacheKey, 0, null);
            $this->sendJson([], 4031, '请登录');
        }
        $this->jwtCode = $jwtCode;
        $this->uid = $jwtCode['uid'];
        
    }

    public function contractList(Request $request)
    {
        $this->sendGet(function() use($request) {
            $limit = $request->get('limit');
            $offset = $request->get('offset');
            $order = $request->get('order');
            $option['query'][] = [
                'key' => 'user_id',
                'operator' => '=',
                'value' => $this->uid
            ];
            $data = ContractService::getContractList($limit, $offset, $order, $option);
            $this->sendDataTable($data);
        });
    }

    public function contractDetail(Request $request)
    {
        $this->sendGet(function() use($request) {
            $id = $request->get('id');
            $data = ContractService::getContractDetail($id);
            $this->sendJson($data);
        });
    }

    public function feeList(Request $request)
    {
        $this->sendGet(function() use($request) {
            $limit = $request->get('limit');
            $offset = $request->get('offset');
            $order = $request->get('order');
            $data = FeeService::getFeeList($limit, $offset, $order);

            $this->sendDataTable($data);
        });
    }

    public function feeTypeList(Request $request, $type)
    {
        $this->sendGet(function() use($request, $type) {
            $limit = $request->get('limit');
            $offset = $request->get('offset');
            $order = $request->get('order');
            $status = $request->get('status');
            $option = [];
            if ($type) {
                $option['query'][] = [
                    'key' => 'type',
                    'operator' => '=',
                    'value' => $type
                ];
            }
            if ($status) {
                $option['query'][] = [
                    'key' => 'status',
                    'operator' => '=',
                    'value' => $status
                ];
            }
            $data = FeeService::getFeeList($limit, $offset, $order, $option);

            $this->sendDataTable($data);
        });
    }

    public function feeDetail(Request $request)
    {
        $this->sendGet(function() use($request) {
            $id = $request->get('id');
            $data = FeeService::getFeeDetail($id);
            $this->sendJson($data);
        });
    }

    public function file(Request $request)
    {
        $this->sendGet(function() use($request) {
            $data = UserService::getTeacherDetail(0, $this->uid);
            $this->sendJson($data);
        });
    }

    public function noticeList(Request $request)
    {
        $this->sendGet(function() use($request) {
            $limit = $request->get('limit');
            $offset = $request->get('offset');
            $order = $request->get('order');
            $data = NoticeService::getNoticeList($limit, $offset, $order);
            $this->sendDataTable($data);
        });
    }

    public function noticeDetail(Request $request)
    {
        $this->sendGet(function() use($request) {
            $id = $request->get('id');
            $data = NoticeService::getNoticeDetail($id);
            $this->sendJson($data);
        });
    }

    public function programList(Request $request)
    {
        $this->sendGet(function() use($request) {
            $limit = $request->get('limit');
            $offset = $request->get('offset');
            $order = $request->get('order');
            $option['query'][] = [
                'key' => 'state', 'operator' => '=', 'value' => 1
            ];
            $data = ProgramService::getProgramList($limit, $offset, $order, $option);
            foreach ($data['rows'] as &$row) {
                $programUser = ProgramUser::where('user_id', $this->uid)->where('program_id', $row['id'])->first();
                if (!$programUser) {
                    $row['is_apply'] = '未申请';
                } else {
                    if ($programUser->status == 0) {
                        $row['is_apply'] = '待审核';
                    } elseif ($programUser->status == 1) {
                        $row['is_apply'] = '已通过';
                    } elseif ($programUser->status == 2) {
                        switch ($programUser->state) {
                            case 0 : $row['is_apply'] = '可选房';break;
                            case 1 : $row['is_apply'] = '已选房';break;
                            case 2 : $row['is_apply'] = '选房成功';break;
                            case 3 : $row['is_apply'] = '选房失败';break;
                        }
                    } elseif ($programUser->status == 3) {
                        $row['is_apply'] = '已拒绝';
                    }
                }
            }
            $this->sendDataTable($data);
        });
    }

    public function programDetail(Request $request)
    {
        $this->sendGet(function() use($request) {
            $id = $request->get('id');
            $data = ProgramService::getProgramDetail($id);
            $programUser = ProgramUser::where('program_id', $id)->where('user_id', $this->uid)->first();
            $select = [];
            if ($programUser) {
                $select = [
                    'state' => $programUser->state,
                    'status' => $programUser->status,
                    'start_at' => local_date($programUser->start_at, 'Y-m-d H:i:s'),
                    'end_at' => local_date($programUser->end_at, 'Y-m-d H:i:s'),
                ];
            } else {
                $select = ['status' => 99];
            }
            $data['select'] = $select;
            $this->sendJson($data);
        });
    }

    public function rentList(Request $request)
    {
        $this->sendGet(function() use($request) {
            $limit = $request->get('limit');
            $offset = $request->get('offset');
            $order = $request->get('order');
            $option['query'][] = [
                'key' => 'user_id',
                'operator' => '=',
                'value' => $this->uid
            ];
            $data = RentService::getRentList($limit, $offset, $order, $option);
            $this->sendDataTable($data);
        });
    }

    public function rentDetail(Request $request)
    {
        $this->sendGet(function() use($request) {
            $id = $request->get('id');
            $data = RentService::getRentDetail($id);
            $this->sendJson($data);
        });
    }

    public function repairList(Request $request)
    {
        $this->sendGet(function() use($request) {
            $limit = $request->get('limit');
            $offset = $request->get('offset');
            $order = $request->get('order');
            $option['query'][] = [
                'key' => 'user_id',
                'operator' => '=',
                'value' => $this->uid
            ];
            $data = RepairService::getRepairList($limit, $offset, $order, $option);
            $this->sendDataTable($data);
        });
    }

    public function repairDetail(Request $request)
    {
        $this->sendGet(function() use($request) {
            $id = $request->get('id');
            $data = RepairService::getRepairDetail($id);
            $this->sendJson($data);
        });
    }

    public function repairSave(Request $request)
    {
        $this->sendPost(function() use($request) {
            $data = $request->get('data');
            $data['user_id'] = $this->uid;
            RepairService::saveRepair($data);
            $this->sendJson([], 200, '保存成功');
        });
    }

    public function repairDelete(Request $request)
    {
        $this->sendPost(function() use($request) {
            $id = $request->get('id');
            RepairService::deleteRepair($id);
            $this->sendJson([], 200, '删除成功');
        });
    }

    public function programApartList(Request $request, $programId)
    {
        $this->sendGet(function() use($request, $programId) {
            $limit = $request->get('limit');
            $offset = $request->get('offset');
            $order = $request->get('order');
            $data = ApartService::getProgramApartList($programId, $limit, $offset, $order);
            foreach ($data['rows'] as &$row) {
                $userApart = UserApart::where('user_id', $this->uid)->where('apart_id', $row['apart_id'])->first();
                $row['is_selected'] = $userApart == null ? 0 : 1;
            }
            $this->sendDataTable($data);
        });
    }

    public function programApply(Request $request)
    {
        $this->sendPost(function() use($request){
            $id = $request->get('id');
            if (Contract::where('user_id', $this->uid)->where('status', '>', 0)->where('end_at', '>', date('Y-m-d H:i:s', time()))->first()) {
                $this->sendJson([], 200, '您已申请过项目, 不可多次申请');
            }
            if (ProgramUser::where('user_id', $this->uid)->where('program_id', $id)->where('state', '<', 3)->first()) {
                $this->sendJson([], 200, '您已申请过项目, 不可多次申请');
            }
            ProgramService::apply($id, $this->uid);
            $this->sendJson([], 200, '申请成功');
        });
    }

    public function apartSelect(Request $request)
    {
        $this->sendPost(function() use($request){
            $programId = $request->get('program_id');
            $apartId = $request->get('apart_id');
            $programUser = ProgramUser::where('program_id', $programId)->where('user_id', $this->uid)->where('status', 2)->first();
            if (!$programUser) {
                $this->sendJson([], 403, '您未申请该项目或没有选房资格');
            }
            if (!(strtotime($programUser->start_at) < time() && strtotime($programUser->end_at) > time())) {
                $this->sendJson([], 403, '没到选房时间或选房时间已过期');
            }
            $userApart = UserApart::where('program_id', $programId)->where('user_id', $this->uid)->first();
            if ($userApart) {
                if ($userApart->apart_id == $apartId) {
                    $this->sendJson([], 403, '您已选择了该房源');
                } else {
                    $this->sendJson([], 403, '您不能选择多个房源');
                }
            }
            if (UserApart::where('apart_id', $apartId)->where('program_id', $programId)->first()) {
                $this->sendJson([], 403, '该房源已被选择, 请选择其它房源');
            }
            ApartService::select($programId, $apartId, $this->uid);
            $this->sendJson([], 200, '选择成功');
        });
    }

    public function apartList(Request $request)
    {
        $this->sendGet(function() use($request) {
            $limit = $request->get('limit');
            $offset = $request->get('offset');
            $order = $request->get('order');
            $data = ApartService::getTeacherApartList($limit, $offset, $order);
            $this->sendDataTable($data);
        });
    }

    public function apartDetail(Request $request)
    {
        $this->sendGet(function() use($request) {

            $data = ApartService::getUserApart($this->uid);
            $this->sendJson($data);
        });
    }

    public function fileSave(Request $request)
    {
        $this->sendPost(function() use($request){
            $data = $request->get('data');
             $data['user_id'] = $this->uid;
            UserService::saveTeacher($data);
            $this->sendJson([], 200, '保存成功');
        });
    }

    public function units(Request $request)
    {
        $this->sendGet(function() use($request) {
            $data = UserService::getUnits();
            $this->sendJson($data);
        });
    }

    public function apartApply(Request $request)
    {
        $this->sendPost(function() use($request){
            $id = $request->get('id');
            $userId = $this->uid;
            ApartService::saveUserApart($id, $userId);
            $this->sendJson([], 200, '提交成功');
        });
    }

    public function changeContractProcess(Request $request)
    {
        $this->sendPost(function() use($request){
            $data = $request->get('data');
            ContractService::changeContractProcess($data);
            $this->sendJson([], 200, '提交成功');
        });
    }

    public function retireList(Request $request)
    {
        $this->sendGet(function() use($request) {
            $limit = $request->get('limit');
            $offset = $request->get('offset');
            $order = $request->get('order');
            $option['query'][] = [
                'key' => 'user_id',
                'operator' => '=',
                'value' => $this->uid
            ];
            $data = RetireService::getRetireList($limit, $offset, $order, $option);
            $this->sendDataTable($data);
        });
    }

    public function retireDetail(Request $request)
    {
        $this->sendGet(function() use($request) {
            $id = $request->get('id');
            $contractId = $request->get('contract_id');
            $data = RetireService::getRetireDetail($id, $contractId);
            $this->sendJson($data);
        });
    }

    public function retireCreate(Request $request)
    {
        $this->sendPost(function() use($request){
            $data = $request->get('data');
            $data['user_id'] = $this->uid;
            $data['type'] = 2;
            $data['created_by'] = $this->uid;
            $retire = RetireService::getRetireDetail(null, $data['contract_id']);
            $message = '提交成功';
            if ($retire) {
                $message = $this->isRetireOver($retire) ? '退房已完成,无需操作' : '您已发起退房,请等待管理员审核';
            } else {
                $data['checkout_at'] = date('Y-m-d H:i:s', time());
                $data['is_rent_pay'] = 0;
                $data['is_water_fee_pay'] = 0;
                $data['is_electric_fee_pay'] = 0;
                $data['is_gas_fee_pay'] = 0;
                $data['is_device_safe'] = 0;
                RetireService::saveRetire($data);
            }
            $this->sendJson([], 200, $message);
        });
    }

    public function apartRelease(Request $request)
    {
        $this->sendPost(function() use($request){
            $apartId = $request->get('apart_id');
            ApartService::releaseUserApart($apartId, $this->uid);
            $this->sendJson([], 200, '取消成功');
        });
    }

    public function changeFeePay(Request $request)
    {
        $this->sendPost(function() use($request){
            $data = $request->get('data');
            FeeService::changePayType($data);
            $this->sendJson([], 200, '操作成功');
        });
    }

    public function changeRentPay(Request $request)
    {
        $this->sendPost(function() use($request){
            $data = $request->get('data');
            RentService::changePayType($data);
            $this->sendJson([], 200, '操作成功');
        });
    }

    public function orderCreate(Request $request)
    {
        $this->sendPost(function() use($request){
            $fee = $request->get('fee');
            $tag = $request->get('tag');
            $xykOrder=new XykOrder();
            $data = $xykOrder->createOrder($fee, $tag);
            $this->sendJson($data, 200, 'OK');
        });
    }

    public function orderSelect(Request $request)
    {
        $this->sendGet(function() use($request){
            $orderId = $request->get('order_id');
            $tag = $request->get('tag');
            $xykOrder=new XykOrder();
            $data = $xykOrder->selectOrder($orderId, $tag);
            $this->sendJson($data, 200, 'OK');
        });
    }

    private function isRetireOver($retire)
    {
        if (!$retire['is_rent_pay']) {
            return false;
        }
        if (!$retire['is_water_fee_pay']) {
            return false;
        }
        if (!$retire['is_electric_fee_pay']) {
            return false;
        }
        if (!$retire['is_gas_fee_pay']) {
            return false;
        }
        if (!$retire['is_device_safe']) {
            return false;
        }
        return true;
    }
}